package repository

import (
	"context"
	"ehsm_kms/internal/model"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"go.uber.org/zap"
	"time"
)

type QuotePolicyRepository interface {
	Store(ctx context.Context, appid, mrEnclave, mrSigner string) error
	FindByPolicyId(ctx context.Context, appid, policyId string) (string, string, error)
	FindModelByPolicyId(ctx context.Context, appid, policyId string) (m *model.QuotePolicy, err error)
}

func NewQuotePolicyRepository(r *Repository, log *zap.Logger) QuotePolicyRepository {
	return &quotePolicyRepository{
		Repository: r,
		log:        log,
	}
}

type quotePolicyRepository struct {
	*Repository
	log *zap.Logger
}

func (r *quotePolicyRepository) Store(ctx context.Context, appid, mrEnclave, mrSigner string) error {

	ct := time.Now().UnixMicro()
	policyId := uuid.New()
	m := model.QuotePolicy{
		Id:         fmt.Sprintf("quote_policy:%s", policyId.String()),
		Appid:      appid,
		PolicyId:   policyId.String(),
		MrEnclave:  mrEnclave,
		MrSigner:   mrSigner,
		CreateTime: ct,
	}
	rev, err := r.db.Put(ctx, m.Id, m)
	if err != nil {
		return err
	}
	fmt.Println("createQuote rev:", rev)
	return nil
}

func (r *quotePolicyRepository) FindByPolicyId(ctx context.Context, appid, policyId string) (string, string, error) {
	query := map[string]any{
		"selector": map[string]string{
			"appid":    appid,
			"policyId": policyId,
		},
		"fields": []string{"mr_enclave", "mr_signer"},
		"limit":  1,
	}
	rows, err := r.db.Find(ctx, query)
	if err != nil {
		return "", "", err
	}
	if !rows.Next() {
		return "", "", errors.New("policyId error")
	}
	m := map[string]string{}
	err = rows.ScanDoc(&m)
	if err != nil {
		return "", "", err
	}
	return m["mr_enclave"], m["mr_signer"], nil
}

func (r *quotePolicyRepository) FindModelByPolicyId(ctx context.Context, appid, policyId string) (m *model.QuotePolicy, err error) {
	query := map[string]any{
		"selector": map[string]string{
			"appid":    appid,
			"policyId": policyId,
		},
		"fields": []string{"mr_enclave", "mr_signer", "createTime"},
		"limit":  1,
	}
	rows, err := r.db.Find(ctx, query)
	if err != nil {
		return
	}
	if !rows.Next() {
		return nil, errors.New("policyId error")
	}
	m = &model.QuotePolicy{}
	err = rows.ScanDoc(&m)
	return
}
